#include "BufferFrame.h"

BufferFrame::BufferFrame(unsigned pageId, char* data) : pageId(pageId), dirty(false), data(data), secondChance(true), isDummyFrame(false)
{
    SEM_CREATE(this->pageLock);
}

BufferFrame::BufferFrame(unsigned pageId, char* data, bool secondChance, bool isDummy) : pageId(pageId), dirty(false), data(data), secondChance(secondChance), isDummyFrame(isDummy)
{
    SEM_CREATE(this->pageLock);
}

/**
A buffer frame should offer a method giving access to
the buffered page.2 Except for the buffered page, BufferFrame objects can also
store control information (page ID, dirtyness, . . . ).
*/
void* BufferFrame::getData()
{
    return this->data;
}

unsigned BufferFrame::getPageId()
{
    return this->pageId;
}

bool BufferFrame::isDummy()
{
    return this->isDummyFrame;
}

/**
Returns if a buffer frame is marked as dirty.
*/
bool BufferFrame::isDirty()
{
    return this->dirty;
}

int BufferFrame::tryLock()
{
    return SEM_TRYWRITELOCK(this->pageLock);
}

void BufferFrame::doLock(bool exclusive)
{
    if (exclusive)
    {
        SEM_WRITELOCK(this->pageLock);
    }
    else
    {
        SEM_READLOCK(this->pageLock);
    }
}

void BufferFrame::releaseLock()
{
    SEM_UNLOCK(this->pageLock);
}

bool BufferFrame::hasSecondChance()
{
    return this->secondChance;
}

void BufferFrame::setSecondChance(bool chance)
{
    this->secondChance = chance;
}

void BufferFrame::markDirty(bool dirty)
{
    this->dirty = this->dirty || dirty;
}

const bool BufferFrame::operator<(const BufferFrame& other)
{
    return this->pageId < other.pageId;
}

BufferFrame::~BufferFrame()
{
    SEM_DESTROY(this->pageLock);
    delete[] this->data;
}
